#pragma once

#define TOKENS_PER_LIST_BLOCK 100

typedef enum eTokenType 
{ 
	none_Token = 0, // Is set to zero to signal the end of array-list.
	id_Token, 
	number_Token,
	ar_op_Token, 
	rel_op_Token, 
	assign_Token, 
	main_Token, 
	block_Token,
	begin_Token, 
	start_Token,
	end_Token,
	finish_Token,
	const_Token,
	exception_Token,
	integer_Token,
	real_Token, 
	until_Token,
	colon_Token, 
	semicolon_Token,
	leftbracket_Token,
	rightbracket_Token,
	if_Token, 
	then_Token, 
	else_Token, 
	fi_Token,
	do_Token, 
	od_Token, 
	throw_Token, 
	EOF_Token
} eTokenType;

typedef enum eType 
{ 
	none_Type,
	integer_Type,
	real_Type,
	boolean_Type,
} eType;

static const char *typeStrings[] = {	
	"undefined",
	"integer",
	"real",
	"boolean"
};

typedef enum eKind
{
	none_Kind = 0,
	variable_Kind = 1,
	constant_Kind = 2,
	exception_Kind = 4
} eKind;

static const char *kindStrings[] = {	
	"undefined",
	"variable",
	"constant",
	0,
	"exception"
};

typedef enum eSemanticError
{
	TypeMismatch_semantic,
	KindMismatch_semantic,
	Undefined_semantic,
	Redefinition_semantic
} eSemanticError;

typedef struct Token
{
	eTokenType type;
	int lineNumber;
	int columnNumber;
	char* lexeme;
} Token;

static const eTokenType tokenSeparators[] = {
	colon_Token,
	semicolon_Token,
	leftbracket_Token,
	rightbracket_Token,
	none_Token
};

static const eTokenType tokenKeywords[] = {
	main_Token, 
	block_Token,
	begin_Token, 
	start_Token,
	end_Token,
	finish_Token,
	const_Token,
	exception_Token,
	integer_Token,
	real_Token,
	if_Token,
	then_Token,
	else_Token,
	fi_Token,
	do_Token,
	until_Token,
	od_Token,
	throw_Token,
	none_Token
};

static const char *tokenStrings[] = {	
	"N/A",
	"id", 
	"number",
	"arithmetic operation", 
	"comparison operation", 
	":=", 
	"main", 
	"block",
	"begin", 
	"start",
	"end",
	"finish",
	"const",
	"exception",
	"integer",
	"real", 
	"until",
	":", 
	";",
	"(",
	")",
	"if", 
	"then", 
	"else", 
	"fi",
	"do", 
	"od", 
	"throw", 
	"End of file"
};

